package com.lzy.webapi.facade;

import com.alibaba.fastjson.JSONArray;
import com.lzy.base.apis.SysUserRoleServiceApi;
import com.lzy.base.dtos.SysUserRoleDto;
import com.lzy.common.apis.AreaServiceApi;
import com.lzy.common.dtos.AreaDto;
import com.lzy.coupon.apis.MotorcycleServiceApi;
import com.lzy.coupon.apis.MotorcycleSpecServiceApi;
import com.lzy.coupon.dtos.MotorcycleDto;
import com.lzy.coupon.dtos.MotorcycleSpecDto;
import com.lzy.framework.core.datasource.multiple.DataSource;
import com.lzy.framework.core.datasource.multiple.DataSourceHolder;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.exceptions.XBusinessException;
import com.lzy.framework.core.orm.db.Pager;
import com.lzy.framework.core.utils.DateUtil;
import com.lzy.framework.core.utils.DozerUtils;
import com.lzy.framework.core.utils.StringUtil;
import com.lzy.framework.tools.commons.BigDecimalUtil;
import com.lzy.framework.tools.date.DateStyle;
import com.lzy.framework.tools.date.DateUtils;
import com.lzy.framework.tools.kv.KvClient;
import com.lzy.framework.tools.kv.detail.DistributeLockProcessor;
import com.lzy.member.apis.MemberUserServiceApi;
import com.lzy.member.dtos.MemberUserDto;
import com.lzy.order.apis.OrderApi;
import com.lzy.order.constants.CommonConstants;
import com.lzy.order.domain.OrderMoneyDO;
import com.lzy.order.dtos.BaseOrderDTO;
import com.lzy.order.dtos.OrderInfoDTO;
import com.lzy.order.dtos.OrderMoneyDTO;
import com.lzy.order.entity.OrderInfo;
import com.lzy.order.service.OrderMoneyService;
import com.lzy.order.service.OrderService;
import com.lzy.order.service.SerialNumberService;
import com.lzy.payment.apis.PayApi;
import com.lzy.payment.apis.PayBillApi;
import com.lzy.payment.apis.PayMemberAccountApi;
import com.lzy.payment.dtos.memberAccount.PayMemberAccountDTO;
import com.lzy.payment.dtos.pay.CommonPayDTO;
import com.lzy.payment.dtos.payBill.PayBillDTO;
import com.lzy.product.apis.*;
import com.lzy.product.constants.AgentOrderEnum;
import com.lzy.product.dtos.OrderPayCodeDto;
import com.lzy.product.dtos.ProductUserDto;
import com.lzy.product.dtos.ProjectDto;
import com.lzy.product.dtos.agent.*;
import com.lzy.webapi.request.AgentOrderParamRequest;
import com.lzy.webapi.request.AgentOrderRequest;
import com.lzy.webapi.response.AgentOrderResponse;
import com.lzy.webapi.response.PriceResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class AgentOrderFacade {

    @Autowired
    private AgentProtocolProductServiceApi agentProtocolProductServiceApi;

    @Autowired
    private SerialNumberService serialNumberService;

    @Autowired
    private AgentOrderInfoServiceApi agentOrderInfoServiceApi;

    @Autowired
    private ProductUserServiceApi productUserServiceApi;

    @Autowired
    private AreaServiceApi areaServiceApi;

    @Autowired
    private MemberUserServiceApi memberUserServiceApi;

    @Autowired
    private AgentProtocolServiceApi agentProtocolServiceApi;

    @Autowired
    private AgentMemberProtocolServiceApi agentMemberProtocolServiceApi;

    @Autowired
    private KvClient kvClient;

    @Autowired
    private AgentProductServiceApi agentProductServiceApi;

    @Autowired
    private PayBillApi payBillApi;

    @Autowired
    private AgentOrderYieldRatioServiceApi agentOrderYieldRatioServiceApi;

    @Autowired
    private AgentProtocolYieldRatioServiceApi agentProtocolYieldRatioServiceApi;

    @Autowired
    private OrderPayCodeServiceApi orderPayCodeServiceApi;

    @Autowired
    private PayApi payApi;

    @Autowired
    private AgentProductProjectServiceApi agentProductProjectServiceApi;

    @Autowired
    private MotorcycleSpecServiceApi motorcycleSpecServiceApi;

    @Autowired
    private MotorcycleServiceApi motorcycleServiceApi;

    @Autowired
    private AgentProtocolCommissionServiceApi agentProtocolCommissionServiceApi;

    @Autowired
    private ProjectServiceApi projectServiceApi;

    @Autowired
    private AgentOrderProjectRecordServiceApi agentOrderProjectRecordServiceApi;

    @Autowired
    private AgentPromoteServiceApi agentPromoteServiceApi;

    @Autowired
    private PayMemberAccountApi payMemberAccountApi;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderMoneyService orderMoneyService;

    @Autowired
    private SysUserRoleServiceApi sysUserRoleServiceApi;


    private static final Logger LOGGER = LoggerFactory.getLogger(AgentOrderFacade.class);

    /**
     * 创建协议订单
     * 注意：productUserDto是一个维护了多次的对象
     *
     * @param userId
     * @param agentOrderRequest
     * @return
     */
    public AgentOrderInfoDto createProtocolOrder(Long userId, AgentOrderRequest agentOrderRequest) {
        LOGGER.info("创建协议订单start");
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        //停止支付时间（分钟）
        Integer delayMinute = 30;
        Ensure.that(agentOrderRequest).isNotNull("04000001");
        AgentOrderInfoDto agentOrderInfoDto = DozerUtils.map(agentOrderRequest, AgentOrderInfoDto.class);
        AreaDto areaDto = areaServiceApi.findAreaByCityCode(agentOrderRequest.getCityCode());
        Ensure.that(areaDto).isNotNull("06000001");
        Ensure.that(agentOrderRequest.getSourceId()).isNotNull("06000010");
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_PRODUCT);
        AgentProtocolDto agentProtocolDto = agentProtocolServiceApi.findById(agentOrderRequest.getSourceId());
        Ensure.that(agentProtocolDto).isNotNull("06000010");
        //生成订单号
        agentOrderInfoDto.setOrderId(serialNumberService.createSerialNumber(CommonConstants.Biz.AGENT_AGREEMENT, userId.toString()));
        //设置订单状态
        agentOrderInfoDto.setStatus(AgentOrderEnum.OrderStatus.NoPay.getCode());
        //设置订单类型
        agentOrderInfoDto.setType(AgentOrderEnum.OrderType.AgentAgreement.getCode());
        agentOrderInfoDto.setUserId(userId);
        ProductUserDto productUserDto = productUserServiceApi.queryAgentByphone(agentOrderInfoDto.getPhone());
        Ensure.that(productUserDto).isNull("06000020");
        //如果用户不存在  新增用户
        productUserDto = productUserServiceApi.queryByPhone(agentOrderInfoDto.getPhone());
        //如果数据库中不存在该用户  则新增  否则  更新
        if (productUserDto == null) {
            LOGGER.info("sys_user_admin用户不存在,新增用户");
            productUserDto = new ProductUserDto();
            productUserDto.setPhone(agentOrderRequest.getPhone());
            productUserDto.setLoginName(agentOrderRequest.getPhone());
            productUserDto.setCityCode(agentOrderRequest.getCityCode());
            productUserDto.setAgentNumber(generateNumber(agentOrderRequest.getCityCode()));
            productUserDto.setAgentProtocol(agentOrderRequest.getSourceId());
            productUserDto.setSystemId(agentProtocolDto.getSystemId());
            productUserDto.setName(agentOrderRequest.getName());
            productUserDto.setUserId(userId);
            productUserDto.setAgentTime(DateUtils.getNow(DateStyle.YYYY_MM_DD_HH_MM_SS));
            Ensure.that(productUserServiceApi.insert(productUserDto)).isNotNull("06000007");
        } else {
            //如果sys_user_admin中存在该人  更新该人的部分信息
            LOGGER.info("sys_user_admin用户存在,更新用户信息");
            productUserDto.setAgentNumber(generateNumber(agentOrderRequest.getCityCode()));
            productUserDto.setAgentProtocol(agentOrderRequest.getSourceId());
            productUserDto.setSystemId(agentProtocolDto.getSystemId());
            productUserDto.setName(agentOrderRequest.getName());
            productUserDto.setUserId(userId);
            productUserDto.setCityCode(agentOrderRequest.getCityCode());
            productUserDto.setAgentTime(DateUtils.getNow(DateStyle.YYYY_MM_DD_HH_MM_SS));
            Ensure.that(productUserServiceApi.update(productUserDto)).isTrue("06000008");
        }
        //新增用户后重新设置对象防止空指针
        productUserDto = productUserServiceApi.queryByPhone(agentOrderInfoDto.getPhone());
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        MemberUserDto memberUserDto = memberUserServiceApi.findMemberByMobile(agentOrderRequest.getPhone());
        if (memberUserDto != null) {
            LOGGER.info("2.1 member_user存在，姓名为" + memberUserDto.getName());
            memberUserDto.setCityName(areaDto.getName());
            memberUserDto.setCityCode(areaDto.getCityCode());
            memberUserDto.setName(agentOrderRequest.getName());
            memberUserDto.setIDNumber(agentOrderRequest.getIdCard());
            memberUserDto.setAccount(agentOrderRequest.getPhone());
            memberUserDto.setAddress(areaDto.getName());
            Ensure.that(memberUserServiceApi.updateMemberInfo(memberUserDto).intValue() != 0).isTrue("06000008");
        } else {
            LOGGER.info("2.1 member_user不存在");
            memberUserDto = new MemberUserDto();
            memberUserDto.setAddress(areaDto.getName());
            memberUserDto.setAccount(agentOrderRequest.getPhone());
            memberUserDto.setIDNumber(agentOrderRequest.getIdCard());
            memberUserDto.setName(agentOrderRequest.getName());
            memberUserDto.setCityCode(areaDto.getCityCode());
            Ensure.that(memberUserServiceApi.addMember(memberUserDto)).isNotNull("06000007");
        }
        memberUserDto = memberUserServiceApi.findMemberByMobile(agentOrderRequest.getPhone());
        DataSourceHolder.clearDataSource();
        AgentMemberProtocolDto agentMemberProtocolDto = new AgentMemberProtocolDto();
        agentMemberProtocolDto.setCreateUser(userId);
        agentMemberProtocolDto.setProtocolId(agentOrderRequest.getSourceId());
        agentMemberProtocolDto.setMemberId(productUserDto.getId());
        Ensure.that(agentMemberProtocolServiceApi.insert(agentMemberProtocolDto).intValue() != 0).isTrue("06000009");
        agentOrderInfoDto.setMemberId(productUserDto.getId());
        //设置创建人
        agentOrderInfoDto.setCreateUser(userId);
        agentOrderInfoDto.setCityName(areaDto.getName());
        //支付截止时间 +30min
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, delayMinute);
        agentOrderInfoDto.setExpiredTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(nowTime.getTime()));
        //原价
        agentOrderInfoDto.setNormalPrice(agentProtocolDto.getPrice());
        //售价
        agentOrderInfoDto.setSalePrice(agentProtocolDto.getPrice());
        //总价
        agentOrderInfoDto.setMoneyCount(agentProtocolDto.getPrice() == null ? BigDecimal.ZERO : agentProtocolDto.getPrice()
                .multiply(agentOrderRequest.getCount() == null ? BigDecimal.ONE : new BigDecimal(agentOrderRequest.getCount())));
        Long orderId = agentOrderInfoServiceApi.insert(agentOrderInfoDto);
        Ensure.that(orderId).isNotNull("04000002");
        if (agentOrderRequest.getYieldRatioId() != null) {
            AgentProtocolYieldRatioDto agentProtocolYieldRatioDto = agentProtocolYieldRatioServiceApi.findById(agentOrderRequest.getYieldRatioId());
            Ensure.that(agentProtocolYieldRatioDto).isNotNull("06000011");
            AgentOrderYieldRatioDto agentOrderYieldRatioDto = new AgentOrderYieldRatioDto();
            agentOrderYieldRatioDto.setOrderId(orderId);
            agentOrderYieldRatioDto.setMemberId(memberUserDto.getId());
            agentOrderYieldRatioDto.setType(2);
            agentOrderYieldRatioDto.setSourceId(agentOrderRequest.getSourceId());
            agentOrderYieldRatioDto.setPrice(agentOrderInfoDto.getMoneyCount());
            agentOrderYieldRatioDto.setCashbackTime(agentProtocolYieldRatioDto.getCashbackTime());
            agentOrderYieldRatioDto.setCashbackRatio(agentProtocolYieldRatioDto.getCashbackRatio());
            agentOrderYieldRatioDto.setLimitTime(agentProtocolYieldRatioDto.getCashbackWithdrawal());
            agentOrderYieldRatioDto.setStatus(0);
            Ensure.that(agentOrderYieldRatioServiceApi.insert(agentOrderYieldRatioDto)).isNotNull("06000012");
        }
        Ensure.that(saveAgentOrderProjectRecord(agentOrderInfoDto)).isTrue("06000019");
        return agentOrderInfoServiceApi.findByOrderId(orderId);
    }

    /**
     * 保存代理商订单协议产品包含项记录
     *
     * @param agentOrderInfoDto
     * @return
     */
    private Boolean saveAgentOrderProjectRecord(AgentOrderInfoDto agentOrderInfoDto) {
        if (agentOrderInfoDto != null) {
            List<AgentProductProjectDto> agentProductProjectDtoList = agentProductProjectServiceApi.selectByOrderId(agentOrderInfoDto.getOrderId());
            AgentOrderProjectRecordDto agentOrderProjectRecordDto = new AgentOrderProjectRecordDto();
            for (AgentProductProjectDto agentProductProjectDto : agentProductProjectDtoList) {
                //添加固定项
                if (agentProductProjectDto.getType().equals(0)) {
                    agentOrderProjectRecordDto.setOrderId(agentOrderInfoDto.getOrderId());
                    agentOrderProjectRecordDto.setCount(agentProductProjectDto.getContainNum());
                    agentOrderProjectRecordDto.setPrice(agentProductProjectDto.getPrice());
                    agentOrderProjectRecordDto.setProjectId(agentProductProjectDto.getProjectId());
                    agentOrderProjectRecordDto.setType(agentProductProjectDto.getType());
                    agentOrderProjectRecordDto.setProjectType(projectServiceApi.getById(agentProductProjectDto.getProjectId()).getType());
                    agentOrderProjectRecordDto.setValidTime(agentProductProjectDto.getValidTime());
                    agentOrderProjectRecordServiceApi.insert(agentOrderProjectRecordDto);
                } else if (agentProductProjectDto.getType().equals(1)) {
                    if (agentOrderInfoDto.getProjectId() != null && agentOrderInfoDto.getProjectId().equals(agentProductProjectDto.getProjectId())) {
                        agentOrderProjectRecordDto.setOrderId(agentOrderInfoDto.getOrderId());
                        agentOrderProjectRecordDto.setCount(agentProductProjectDto.getContainNum());
                        agentOrderProjectRecordDto.setPrice(agentProductProjectDto.getPrice());
                        agentOrderProjectRecordDto.setProjectId(agentProductProjectDto.getProjectId());
                        agentOrderProjectRecordDto.setType(agentProductProjectDto.getType());
                        agentOrderProjectRecordDto.setProjectType(projectServiceApi.getById(agentProductProjectDto.getProjectId()).getType());
                        agentOrderProjectRecordDto.setValidTime(agentProductProjectDto.getValidTime());
                        agentOrderProjectRecordServiceApi.insert(agentOrderProjectRecordDto);
                    }
                }
            }
            return true;
        }
        return false;
    }


    /**
     * 生成代理商编号 地区编码+年月+4位流水号
     *
     * @param cityCode
     * @return
     */
    private String generateNumber(Integer cityCode) {
        return kvClient.lockForProcess(AgentOrderEnum.AGENT_NUMBER + cityCode.toString(), 3000, new DistributeLockProcessor<String>() {
            @Override
            public String process() throws XBusinessException {
                SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
                String agentNumber = productUserServiceApi.maxiNumber("^[0-9][0-9][0-9][0-9][0-9][0-9]" + new SimpleDateFormat("yyyyMM").format(new Date()) + "[0-9][0-9][0-9][0-9]$");
                if (StringUtil.isBlank(agentNumber)) {
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(cityCode);
                    stringBuilder.append(format.format(new Date()));
                    stringBuilder.append("0001");
                    return stringBuilder.toString();
                } else {
                    //取得最大编号+1
                    Integer serialNumber = Integer.valueOf(agentNumber.substring(agentNumber.length() - 4, agentNumber.length())) + 1;
                    //不足4位时以0占位
                    String serialNumberStr = serialNumber.toString();
                    while (serialNumberStr.length() < 4) {
                        serialNumberStr = "0" + serialNumberStr;
                    }
                    return agentNumber.substring(0, agentNumber.length() - 4) + serialNumberStr;
                }
            }
        });
    }


    /**
     * 创建产品订单
     *
     * @param userId
     * @param request
     * @return
     */
    public AgentOrderInfoDto createProductOrder(Long userId, AgentOrderRequest request, Integer type) {
        LOGGER.info("创建产品订单start");
        DataSourceHolder.clearDataSource();
        //停止支付时间（分钟）
        Integer delayMinute = 30;
        Ensure.that(request).isNotNull("04000001");
        AgentOrderInfoDto agentOrderInfoDto = DozerUtils.map(request, AgentOrderInfoDto.class);
        agentOrderInfoDto.setOrderId(serialNumberService.createSerialNumber(CommonConstants.Biz.AGENT_AGREEMENT, userId.toString()));
        agentOrderInfoDto.setStatus(AgentOrderEnum.OrderStatus.NoPay.getCode());
        agentOrderInfoDto.setType(AgentOrderEnum.OrderType.AgentProduct.getCode());
        agentOrderInfoDto.setMemberId(userId);
        agentOrderInfoDto.setCreateUser(request.getSaleMan());
        Ensure.that(request.getSourceId()).isNotNull("06000010");
        AgentProductDto agentProductDto = agentProductServiceApi.queryAgentProductById(request.getSourceId());
        Ensure.that(agentProductDto).isNotNull("06000010");
        agentOrderInfoDto.setNormalPrice(agentProductDto.getPrice());
        agentOrderInfoDto.setMoneyCount(agentProductDto.getPrice() == null ? BigDecimal.ZERO : agentProductDto.getPrice()
                .multiply(request.getCount() == null ? BigDecimal.ZERO : new BigDecimal(request.getCount())));
        agentOrderInfoDto.setSalePrice(agentProductDto.getPrice());
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, delayMinute);
        agentOrderInfoDto.setExpiredTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(nowTime.getTime()));
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        MemberUserDto memberUserDto = memberUserServiceApi.findMemberByMobile(request.getPhone());
        MemberUserDto saleMan = memberUserServiceApi.findById(request.getSaleMan());
        if (memberUserDto == null) {
            memberUserDto = new MemberUserDto();
            memberUserDto.setAccount(request.getPhone());
            memberUserDto.setName(request.getName());
            Ensure.that(memberUserServiceApi.addMember(memberUserDto)).isNotNull("06000007");
        }
        memberUserDto = memberUserServiceApi.findMemberByMobile(request.getPhone());
        DataSourceHolder.clearDataSource();
        ProductUserDto productUserDtoSaleMan = productUserServiceApi.queryByPhone(saleMan.getAccount());
        Ensure.that(productUserDtoSaleMan).isNotNull("06000022");
        agentOrderInfoDto.setUserId(productUserDtoSaleMan.getId());
        Long orderId = agentOrderInfoServiceApi.insert(agentOrderInfoDto);
        Ensure.that(orderId).isNotNull("06000014");
        Ensure.that(saveAgentOrderProjectRecord(agentOrderInfoDto)).isTrue("06000019");
        OrderInfoDTO orderInfoDto = new OrderInfoDTO();
        orderInfoDto.setOrderId(agentOrderInfoDto.getOrderId());
        orderInfoDto.setUserId(memberUserDto.getUserId());
        orderInfoDto.setType(15);
        orderInfoDto.setCount(new BigDecimal(request.getCount()));
        PriceResponse priceResponse = priceCalculation(memberUserDto.getId(), request.getSourceId(), request.getCount(), type);
        orderInfoDto.setOrderMoney(priceResponse.getTotalAmount());
        orderInfoDto.setBalancePaid(priceResponse.getBalancePaid());
        orderInfoDto.setOrderAmount(priceResponse.getHandle());
        orderInfoDto.setItemAmount(priceResponse.getTotalAmount());
        orderInfoDto.setStopPayTime(nowTime.getTime());
        orderInfoDto.setType(15);
        orderInfoDto.setMaxStatus(0);
        orderInfoDto.setDesStatus("待支付");
        orderInfoDto.setUserId(memberUserDto.getId());
        orderInfoDto.setTitle(agentProductDto.getName());
        orderInfoDto.setOnline(0);
        JSONArray jsonArray = new JSONArray();
        com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
        jsonObject.put("itemUrl", agentProductDto.getCover());
        jsonObject.put("skuName", agentProductDto.getName());
        jsonObject.put("goodsDes", "X" + agentOrderInfoDto.getCount());
        jsonArray.add(jsonObject);
        orderInfoDto.setGoodAttr(jsonArray.toString());
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        Ensure.that(orderService.createOrder(DozerUtils.map(orderInfoDto, OrderInfo.class)) > 0).isTrue("06000014");
        //扣除用户余额
        PayMemberAccountDTO payMemberAccountDTO = new PayMemberAccountDTO();
        payMemberAccountDTO.setStatus(0);
        payMemberAccountDTO.setType(2);
        payMemberAccountDTO.setUserId(userId);
        List<PayMemberAccountDTO> payMemberAccountDTOList = payMemberAccountApi.queryPayMemberAccountList(payMemberAccountDTO);
        OrderMoneyDTO orderMoneyDTO = new OrderMoneyDTO();
        orderMoneyDTO.setOrderId(orderInfoDto.getOrderId());
        orderMoneyDTO.setBalancePaid(priceResponse.getBalancePaid());
        orderMoneyDTO.setType(15);
        for (PayMemberAccountDTO payMemberAccountDTO1 : payMemberAccountDTOList) {
            if (payMemberAccountDTO1.getRole().equals(2)) {
                BigDecimal cashWithdrawalBalance = payMemberAccountDTO1.getAmount();
                if (priceResponse.getBalancePaid().compareTo(payMemberAccountDTO1.getAmount()) <= 0) {
                    payMemberAccountDTO1.setAmount(payMemberAccountDTO1.getAmount().subtract(priceResponse.getBalancePaid()));
                    orderMoneyDTO.setDirectAmount(priceResponse.getBalancePaid());
                    Ensure.that(payMemberAccountApi.updatePayMemberAccount(payMemberAccountDTO1)).isTrue("06000023");
                    break;
                } else {
                    payMemberAccountDTO1.setAmount(BigDecimal.ZERO);
                    payMemberAccountDTO1.setRole(1);
                    payMemberAccountDTO1 = payMemberAccountApi.queryPayMemberAccount(payMemberAccountDTO1);
                    orderMoneyDTO.setDirectAmount(cashWithdrawalBalance);
                    orderMoneyDTO.setCommissionAmount(priceResponse.getBalancePaid().subtract(cashWithdrawalBalance));
                    payMemberAccountDTO1.setAmount(payMemberAccountDTO1.getAmount().subtract(priceResponse.getBalancePaid().subtract(cashWithdrawalBalance)));
                    Ensure.that(payMemberAccountApi.updatePayMemberAccount(payMemberAccountDTO1)).isTrue("06000023");
                    break;
                }

            }
        }
        if(!BigDecimalUtil.isZeroOrNull(priceResponse.getBalancePaid())) {
            PayBillDTO payBillDTO = new PayBillDTO();
            payBillDTO.setUserId(userId);
            payBillDTO.setRole(1);
            payBillDTO.setType(17);
            payBillDTO.setSerialId(orderId);
            payBillDTO.setAmount(priceResponse.getBalancePaid());
            payBillDTO.setDemo("余额支付");
            payBillApi.createPayBill(payBillDTO);
        }
        Ensure.that(orderMoneyService.insert(DozerUtils.map(orderMoneyDTO, OrderMoneyDO.class))).isTrue("06000023");
        DataSourceHolder.clearDataSource();
        LOGGER.info("创建产品订单end");
        return agentOrderInfoServiceApi.findByOrderId(orderId);
    }

    /**
     * 获取支付二维码地址
     *
     * @return
     */
    public String payCode(Long orderId, Integer payWay) {
        Ensure.that(orderId).isNotNull("04000001");
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_PRODUCT);
        CommonPayDTO commonPayDTO = new CommonPayDTO();
        commonPayDTO.setSerialNumber(orderId.toString());
        commonPayDTO.setWay(payWay);
        AgentOrderInfoDto agentOrderInfoDto = agentOrderInfoServiceApi.findByOrderId(orderId);
        if (agentOrderInfoDto.getType().equals(AgentOrderEnum.OrderType.AgentAgreement.getCode())) {
            commonPayDTO.setType(10);
        } else if (agentOrderInfoDto.getType().equals(AgentOrderEnum.OrderType.AgentProduct.getCode())) {
            commonPayDTO.setType(11);
        } else {
            throw new XBusinessException("暂支支持代理商订单生成二维码");
        }
        if (agentOrderInfoDto.getOrderId() != null && !"".equals(agentOrderInfoDto.getOrderId())) {
            if (agentOrderInfoDto != null && agentOrderInfoDto.getName() != null) {
                commonPayDTO.setSkuName(agentOrderInfoDto.getName());
            }
        } else {
            commonPayDTO.setSkuName("龙之游产品");
        }
        commonPayDTO.setAmount(agentOrderInfoDto.getMoneyCount());
        commonPayDTO.setUserId(agentOrderInfoDto.getMemberId());
        OrderPayCodeDto orderPayCodeDto = checkPayCode(orderId, payWay);
        if (orderPayCodeDto != null) {
            return orderPayCodeDto.getCodeUrl();
        } else {
            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
            Map map = payApi.scanCodePayRequest(commonPayDTO);
            String payCode = (String) map.get("code_url");
            Ensure.that(payCode).isNotBlank("04000009");
            DataSourceHolder.setDataSource(DataSource.DATASOURCE_PRODUCT);
            OrderPayCodeDto payCodeDto = new OrderPayCodeDto();
            payCodeDto.setOrderId(orderId);
            payCodeDto.setPayWay(payWay);
            payCodeDto.setCodeUrl(payCode);
            Ensure.that(orderPayCodeServiceApi.insert(payCodeDto)).isGt(0, "04000011");
            return payCode;
        }
    }

    /**
     * 检查二维码是否存在
     *
     * @param orderId
     * @param payWay
     * @return
     */
    private OrderPayCodeDto checkPayCode(Long orderId, Integer payWay) {
        OrderPayCodeDto orderPayCodeDto = new OrderPayCodeDto();
        orderPayCodeDto.setOrderId(orderId);
        orderPayCodeDto.setPayWay(payWay);
        List<OrderPayCodeDto> list = orderPayCodeServiceApi.selectList(orderPayCodeDto);
        if (list != null) {
            if (list.size() == 1) {
                return list.get(0);
            }
        }
        return null;
    }

    /**
     * 查询订单列表
     *
     * @return
     */
    public List<AgentOrderResponse> query(AgentOrderParamRequest request, Integer type, Long memberId) {
        DataSourceHolder.clearDataSource();
        Ensure.that(type).isNotNull("06000015");
        if (request != null) {
            Pager pager = new Pager();
            pager.setPageSize(request.getPageSize());
            pager.setPageNum(request.getPageNum());
            AgentOrderInfoDto agentOrderInfoDto = new AgentOrderInfoDto();
            agentOrderInfoDto.setCreateTime(request.getStartDate());
            agentOrderInfoDto.setStatus(request.getStatus());
            agentOrderInfoDto.setType(type);
            agentOrderInfoDto.setEndDate(request.getEndDate());
            agentOrderInfoDto.setQueryStr(request.getKey());
            agentOrderInfoDto.setUserId(memberId);
            List<AgentOrderInfoDto> agentOrderInfoDtoList = agentOrderInfoServiceApi.query(pager, agentOrderInfoDto).getRows();
            List result = new ArrayList();
            /*遍历结果  当为代理商协议时 设置reponse 协议相关的内容*/
            for (AgentOrderInfoDto agentOrderInfoDtoResult : agentOrderInfoDtoList) {
                AgentOrderResponse response = DozerUtils.map(agentOrderInfoDtoResult, AgentOrderResponse.class);
                if (type.equals(AgentOrderEnum.OrderType.AgentAgreement.getCode())) {
                    //设置包含项
                    List<AgentProductProjectDto> motor = agentProductProjectServiceApi.selectByOrderId(agentOrderInfoDtoResult.getOrderId());
                    if (!motor.isEmpty()) {
                        //设置汽摩券名称
                        List<AgentOrderResponse.ProjectDtoMini> projectDtoList = new ArrayList<>();
                        AgentOrderResponse.ProjectDtoMini projectDto = response.new ProjectDtoMini();
                        for (AgentProductProjectDto agentProductProjectDto : motor) {
                            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
                            if (agentProductProjectDto.getSpecId() != null) {
                                MotorcycleSpecDto motorcycleSpecDto = motorcycleSpecServiceApi.selectBySpecId(agentProductProjectDto.getSpecId());
                                Ensure.that(motorcycleSpecDto).isNotNull("06000017");
                                String motorName = motorcycleServiceApi.selectMotorcycleDtoByMotorcycleId(motorcycleSpecDto.getMotorcycleId()).getName();
                                projectDto.setMotorName(motorName);
                                projectDto.setContainNum(agentProductProjectDto.getContainNum());
                                projectDtoList.add(projectDto);
                            }
                            DataSourceHolder.clearDataSource();
                            response.setProjectDto(projectDtoList);
                        }
                    }
                    AgentOrderYieldRatioDto agentOrderYieldRatioDto = agentOrderYieldRatioServiceApi.selectByOrderId(agentOrderInfoDtoResult.getOrderId());
                    if (agentOrderYieldRatioDto != null) {
                        AgentOrderResponse.AgentOrderYieldRatioDtoMini agentOrderYieldRatioDtoMini = response.new AgentOrderYieldRatioDtoMini();
                        agentOrderYieldRatioDtoMini.setCashbackRatio(agentOrderYieldRatioDto.getCashbackRatio());
                        agentOrderYieldRatioDtoMini.setCashbackTime(agentOrderYieldRatioDto.getCashbackTime());
                        response.setAgentOrderYieldRatioDto(agentOrderYieldRatioDtoMini);
                    }
                }
                result.add(response);
            }
            return result;
        }
        return null;
    }

    /**
     * 订单详情
     *
     * @param orderId
     * @return
     */
    public AgentOrderResponse orderDetail(Long orderId) {
        Ensure.that(orderId).isNotNull("06000006");
        DataSourceHolder.clearDataSource();
        AgentOrderInfoDto agentOrderInfoDto = DozerUtils.map(agentOrderInfoServiceApi.queryOrderById(orderId), AgentOrderInfoDto.class);
        Ensure.that(agentOrderInfoDto).isNotNull("06000016");
        AgentOrderResponse agentOrderResponse = DozerUtils.map(agentOrderInfoDto, AgentOrderResponse.class);
        agentOrderResponse.setIdCard(informationDesensitization(agentOrderResponse.getIdCard(), 4, '*'));
        if (agentOrderInfoDto.getType().equals(AgentOrderEnum.OrderType.AgentAgreement.getCode())) {
            if (agentOrderInfoDto.getSourceId() != null) {
                AgentProtocolDto agentProtocolDto = agentProtocolServiceApi.selectDetailById(agentOrderInfoDto.getSourceId());
                agentOrderResponse.setProtocolName(agentProtocolDto.getName());
                agentOrderResponse.setProtocolPrice(agentProtocolDto.getPrice());
            }
            /*可销售产品  begin*/
            List<AgentOrderResponse.ProjectDtoMini> list = new ArrayList<>();
            List<AgentProtocolProductDto> protocolProductDtoList = agentProtocolProductServiceApi.selectByProtocolId(agentOrderInfoDto.getSourceId());
            for (AgentProtocolProductDto agentProtocolProductDto : protocolProductDtoList) {
                AgentOrderResponse.ProjectDtoMini projectDtoMini = agentOrderResponse.new ProjectDtoMini();
                projectDtoMini.setContainNum(1);
                projectDtoMini.setMotorName(agentProtocolProductDto.getProductName());
                list.add(projectDtoMini);
            }
            agentOrderResponse.setProjectDto(list);
            /*可销售产品  end*/
            /*销售佣金  begin*/
            AgentOrderResponse.AgentProtocolCommissionMini agentProtocolCommissionMini = agentOrderResponse.new AgentProtocolCommissionMini();
            List<AgentProtocolCommissionDto> agentProtocolCommissionDtoList = agentProtocolCommissionServiceApi.selectByProtocolIdAndSystemId(agentOrderInfoDto.getSourceId(), agentProtocolServiceApi.selectDetailById(agentOrderInfoDto.getSourceId()).getSystemId(), 1);
            if (!agentProtocolCommissionDtoList.isEmpty()) {
                String suffix = agentProtocolCommissionDtoList.get(0).getMode().equals(1) ? "%" : "元";
                agentProtocolCommissionMini.setFirst(agentProtocolCommissionDtoList.get(0).getValue() + suffix);
            } else {
                agentProtocolCommissionMini.setFirst("0元");
            }
            agentProtocolCommissionMini.setSales(salesCommission(agentOrderInfoDto));
            agentOrderResponse.setAgentProtocolCommission(agentProtocolCommissionMini);
            /*销售佣金  end*/
            /*额外赠送  begin*/
            List<AgentProductProjectDto> agentOrderProjectRecordDtoList = agentProductProjectServiceApi.selectByProtocolId(agentOrderInfoDto.getSourceId(), 2);
            if (!agentOrderProjectRecordDtoList.isEmpty()) {
                List<AgentOrderResponse.AgentOrderProjectRecordMini> agentOrderProjectRecordMiniList = new ArrayList<>();
                for (AgentProductProjectDto agentProductProjectDto : agentOrderProjectRecordDtoList) {
                    if (agentProductProjectDto.getType().equals(0)) {
                        AgentOrderResponse.AgentOrderProjectRecordMini agentOrderProjectRecordMini = agentOrderResponse.new AgentOrderProjectRecordMini();
                        agentOrderProjectRecordMini.setCount(agentProductProjectDto.getContainNum());
                        if (agentProductProjectDto.getSpecId() != null) {
                            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
                            MotorcycleSpecDto motorcycleSpecDto = motorcycleSpecServiceApi.selectBySpecId(agentProductProjectDto.getSpecId());
                            MotorcycleDto motorcycleDto = motorcycleServiceApi.findById(motorcycleSpecDto.getMotorcycleId());
                            DataSourceHolder.clearDataSource();
                            agentOrderProjectRecordMini.setName(motorcycleDto.getName() + "(" + agentProductProjectDto.getPrice() + "元)");
                            agentOrderProjectRecordMini.setProjectType(agentProductProjectDto.getType());
                        } else {
                            ProjectDto projectDto = projectServiceApi.getById(agentProductProjectDto.getProjectId());
                            agentOrderProjectRecordMini.setName(projectDto.getName());
                            if (projectDto.getType().equals(5)) {
                                agentOrderProjectRecordMini.setName(projectDto.getName() + "(" + agentProductProjectDto.getPrice() + ")");
                            }
                            agentOrderProjectRecordMini.setProjectType(agentProductProjectDto.getType());
                        }
                        agentOrderProjectRecordMiniList.add(agentOrderProjectRecordMini);
                    } else if (agentProductProjectDto.getProjectId().equals(agentOrderInfoDto.getProjectId())) {
                        AgentOrderResponse.AgentOrderProjectRecordMini agentOrderProjectRecordMini = agentOrderResponse.new AgentOrderProjectRecordMini();
                        agentOrderProjectRecordMini.setCount(agentProductProjectDto.getContainNum());
                        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
                        if (agentProductProjectDto.getSpecId() != null) {
                            MotorcycleSpecDto motorcycleSpecDto = motorcycleSpecServiceApi.selectBySpecId(agentProductProjectDto.getSpecId());
                            MotorcycleDto motorcycleDto = motorcycleServiceApi.findById(motorcycleSpecDto.getMotorcycleId());
                            agentOrderProjectRecordMini.setName(motorcycleDto.getName() + "(" + agentProductProjectDto.getPrice() + "元)");
                        } else {
                            DataSourceHolder.clearDataSource();
                            ProjectDto projectDto = projectServiceApi.getById(agentProductProjectDto.getProjectId());
                            agentOrderProjectRecordMini.setName(projectDto.getName());
                        }
                        DataSourceHolder.clearDataSource();
                        agentOrderProjectRecordMini.setProjectType(agentProductProjectDto.getType());
                        agentOrderProjectRecordMiniList.add(agentOrderProjectRecordMini);
                    }
                }
                agentOrderResponse.setAgentOrderProjectRecord(agentOrderProjectRecordMiniList);
            }

            /*额外赠送  end*/
            /*附加收益  begin*/
            AgentOrderYieldRatioDto agentOrderYieldRatioDto = agentOrderYieldRatioServiceApi.selectByOrderId(orderId);
            if (agentOrderYieldRatioDto != null) {
                AgentOrderResponse.AgentOrderYieldRatioDtoMini agentOrderYieldRatioDtoMini = agentOrderResponse.new AgentOrderYieldRatioDtoMini();
                agentOrderYieldRatioDtoMini.setCashbackTime(agentOrderYieldRatioDto.getCashbackTime());
                agentOrderYieldRatioDtoMini.setCashbackRatio(agentOrderYieldRatioDto.getCashbackRatio());
                agentOrderYieldRatioDtoMini.setDailyIncome(agentOrderYieldRatioDto.getDailyIncome());
                agentOrderYieldRatioDtoMini.setLimitTime(agentOrderYieldRatioDto.getLimitTime());
                agentOrderYieldRatioDtoMini.setPrice(agentOrderYieldRatioDto.getPrice());
                agentOrderResponse.setAgentOrderYieldRatioDto(agentOrderYieldRatioDtoMini);
            }
            /*附加收益  end*/
        }
        return agentOrderResponse;
    }

    /**
     * @param str        要处理的字符串
     * @param plaintext  明文长度
     * @param replaceStr 替换字符串
     * @return
     */
    private String informationDesensitization(String str, Integer plaintext, char replaceStr) {
        if (str == null) {
            return "";
        }
        char[] idNumber = str.toCharArray();
        StringBuffer stringBuffer = new StringBuffer(18);
        for (int i = 0; i < idNumber.length; i++) {
            if (i >= idNumber.length - plaintext) {
                stringBuffer.append(idNumber[i]);
            } else {
                stringBuffer.append(replaceStr);
            }
        }
        return stringBuffer.toString();
    }


    /**
     * 取得销售分佣
     *
     * @param orderInfoDto
     * @return
     */
    private String salesCommission(AgentOrderInfoDto orderInfoDto) {
        if (orderInfoDto == null) {
            return null;
        }
        //标识分佣计算方式 1固定模式 2升级模式
        Integer flag = -1;
        AgentProtocolDto agentProtocolDto = agentProtocolServiceApi.selectDetailById(orderInfoDto.getSourceId());
        List<AgentProtocolCommissionDto> agentProtocolCommissionDtoList = agentProtocolCommissionServiceApi.selectByProtocolIdAndSystemId(agentProtocolDto.getId(), agentProtocolDto.getSystemId(), null);
        for (AgentProtocolCommissionDto agentProtocolCommissionDto : agentProtocolCommissionDtoList) {
            if (agentProtocolCommissionDto.getType().equals(2) && agentProtocolCommissionDto.getPattern().equals(1)) {
                flag = 1;
                break;
            }
            if (agentProtocolCommissionDto.getType().equals(2) && agentProtocolCommissionDto.getPattern().equals(2)) {
                flag = 2;
                break;
            }
        }
        if (flag.equals(-1))
            return "0元";
        String suffix = agentProtocolCommissionDtoList.get(0).getMode().equals(1) ? "%" : "元";
        if (flag.equals(1)) {
            return agentProtocolCommissionDtoList.get(0).getValue() + suffix;
        } else if (flag.equals(2)) {
            BigDecimal sale = agentOrderInfoServiceApi.queryTotalPriceByUserId(orderInfoDto.getMemberId());
            AgentPromoteDto agentPromoteDto = agentPromoteServiceApi.queryByProtocolIdAndCriticalValue(agentProtocolDto.getId(), sale);
            if (agentPromoteDto == null) {
                return BigDecimal.ZERO + suffix;
            }
            return agentProtocolCommissionServiceApi.selectByProtocolIdAndSystemIdAndPromoteId(agentProtocolDto.getId(), agentProtocolDto.getSystemId(), agentPromoteDto.getId()).getValue() + suffix;
        } else return null;
    }


    /**
     * @param memberId  2.1用户id
     * @param productId 产品id
     * @param num       数量
     * @param type      1开启 2关闭
     * @return
     */
    public PriceResponse priceCalculation(Long memberId, Long productId, Integer num, Integer type) {
        Ensure.that(productId).isNotNull("03000001");
        Ensure.that(type != null && (type.equals(1) || type.equals(2))).isTrue("06000021");
        DataSourceHolder.clearDataSource();
        AgentProductDto agentProductDto = agentProductServiceApi.queryAgentProductById(productId);
        BigDecimal price = agentProductDto.getPrice();
        BigDecimal totalAmount = price.multiply(num == null ? BigDecimal.ZERO : new BigDecimal(num));
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        BigDecimal balance = payMemberAccountApi.queryLbBalance(memberId);
        DataSourceHolder.clearDataSource();
        balance = balance == null ? BigDecimal.ZERO : balance;
        BigDecimal balancePaid = BigDecimal.ZERO;
        BigDecimal handle = totalAmount;
        if (type.equals(1)) {
            if (balance.compareTo(totalAmount) >= 0) {
                balancePaid = totalAmount;
                handle = BigDecimal.ZERO;
            } else {
                balancePaid = balance;
                handle = totalAmount.subtract(balance);
            }
        }
        PriceResponse priceResponse = new PriceResponse();
        priceResponse.setBalance(balance);
        priceResponse.setBalancePaid(balancePaid);
        priceResponse.setTotalAmount(totalAmount);
        priceResponse.setHandle(handle);
        return priceResponse;
    }


}
